<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE topic
  PUBLIC "-//OASIS//DTD DITA Composite//EN" "ditabase.dtd">
<topic id="topic1"><title id="dr20941">FETCH</title><body><p id="sql_command_desc">Retrieves rows from a query using a cursor.</p><section id="section2"><title>Synopsis</title><codeblock id="sql_command_synopsis">FETCH [ <varname>forward_direction</varname> { FROM | IN } ] <varname>cursor_name</varname></codeblock><p>where <varname>forward_direction</varname> can be empty or one of:</p><codeblock>    NEXT
    FIRST
    ABSOLUTE <varname>count</varname>
    RELATIVE <varname>count</varname>
    <varname>count</varname>
    ALL
    FORWARD
    FORWARD <varname>count</varname>
    FORWARD ALL</codeblock></section><section id="section3"><title>Description</title><p><codeph>FETCH</codeph> retrieves rows using a previously-created cursor.
</p>
<note>You cannot <codeph>FETCH</codeph> from a <codeph>PARALLEL RETRIEVE CURSOR</codeph>,
  you must <codeph><xref href="RETRIEVE.xml#topic1" type="topic" format="dita"/></codeph>
  the rows from it.</note>
<note>This page describes usage of cursors at the SQL command level. If you are trying to use
        cursors inside a PL/pgSQL function, the rules are different. See <xref
          href="../../analytics/pl_sql.html#topic1" scope="external" format="html">PL/pgSQL function</xref>.</note><p>A cursor has an associated position, which is used by <codeph>FETCH</codeph>.
The cursor position can be before the first row of the query result,
on any particular row of the result, or after the last row of the result.
When created, a cursor is positioned before the first row. After fetching
some rows, the cursor is positioned on the row most recently retrieved.
If <codeph>FETCH</codeph> runs off the end of the available rows then
the cursor is left positioned after the last row. <codeph>FETCH ALL</codeph>
will always leave the cursor positioned after the last row. </p><p>The forms <codeph>NEXT</codeph>, <codeph>FIRST</codeph>, <codeph>ABSOLUTE</codeph>,
          <codeph>RELATIVE</codeph> fetch a single row after moving the cursor appropriately. If
        there is no such row, an empty result is returned, and the cursor is left positioned before
        the first row or after the last row as appropriate. </p><p>The forms using <codeph>FORWARD</codeph> retrieve the indicated number
of rows moving in the forward direction, leaving the cursor positioned
on the last-returned row (or after all rows, if the count exceeds the
number of rows available). Note that it is not possible to move a cursor
position backwards in Greenplum Database, since scrollable cursors are
not supported. You can only move a cursor forward in position using <codeph>FETCH</codeph>.</p><p><codeph>RELATIVE 0</codeph> and <codeph>FORWARD 0</codeph> request
fetching the current row without moving the cursor, that is, re-fetching
the most recently fetched row. This will succeed unless the cursor is
positioned before the first row or after the last row, in which case
no row is returned.</p><sectiondiv id="section4"><b>Outputs</b><p>On successful completion, a <codeph>FETCH</codeph> command returns a
command tag of the form</p><codeblock>FETCH <varname>count</varname></codeblock><p>The count is the number of rows fetched (possibly zero). Note that in
<codeph>psql</codeph>, the command tag will not actually be displayed,
since <codeph>psql</codeph> displays the fetched rows instead.</p></sectiondiv></section><section id="section5"><title>Parameters</title><parml><plentry><pt><varname>forward_direction</varname></pt><pd>Defines the fetch direction and number of rows to fetch. Only forward
fetches are allowed in Greenplum Database. It can be one of the following:</pd></plentry><plentry><pt>NEXT</pt><pd>Fetch the next row. This is the default if direction is omitted.</pd></plentry><plentry><pt>FIRST</pt><pd>Fetch the first row of the query (same as <codeph>ABSOLUTE 1</codeph>).
Only allowed if it is the first <codeph>FETCH</codeph> operation using
this cursor.</pd></plentry><plentry><pt>ABSOLUTE <varname>count</varname></pt><pd>Fetch the specified row of the query. Position after last row if
count is out of range. Only allowed if the row specified by <varname>count</varname>
moves the cursor position forward.</pd></plentry><plentry><pt>RELATIVE <varname>count</varname></pt><pd>Fetch the specified row of the query <varname>count</varname> rows ahead of the
current cursor position. <codeph>RELATIVE 0</codeph> re-fetches the current
row, if any. Only allowed if <varname>count</varname> moves the cursor position forward.</pd></plentry><plentry><pt><varname>count</varname></pt><pd>Fetch the next <varname>count</varname> number of rows (same as <codeph>FORWARD <varname>count</varname></codeph>). </pd></plentry><plentry><pt>ALL</pt><pd>Fetch all remaining rows (same as <codeph>FORWARD ALL</codeph>).
</pd></plentry><plentry><pt>FORWARD</pt><pd>Fetch the next row (same as <codeph>NEXT</codeph>). </pd></plentry><plentry><pt>FORWARD <varname>count</varname></pt><pd>Fetch the next <varname>count</varname> number of rows. <codeph>FORWARD 0</codeph>
re-fetches the current row. </pd></plentry><plentry><pt>FORWARD ALL</pt><pd>Fetch all remaining rows. </pd></plentry><plentry><pt><varname>cursor_name</varname></pt><pd>The name of an open cursor. </pd></plentry></parml></section><section id="section6"><title>Notes</title><p>Greenplum Database does not support scrollable cursors, so you can only
use <codeph>FETCH</codeph> to move the cursor position forward.</p><p><codeph>ABSOLUTE</codeph> fetches are not any faster than navigating
to the desired row with a relative move: the underlying implementation
must traverse all the intermediate rows anyway.</p><p><codeph>DECLARE</codeph> is used to define a cursor. Use <codeph>MOVE</codeph>
to change cursor position without retrieving data.</p></section><section id="section7"><title>Examples</title><p>-- Start the transaction:</p><codeblock>BEGIN;</codeblock><p>-- Set up a cursor:</p><codeblock>DECLARE mycursor CURSOR FOR SELECT * FROM films;</codeblock><p>-- Fetch the first 5 rows in the cursor <codeph>mycursor</codeph>:</p><codeblock>FETCH FORWARD 5 FROM mycursor;
 code  |          title          | did | date_prod  |   kind   |  len
-------+-------------------------+-----+------------+----------+-------
 BL101 | The Third Man           | 101 | 1949-12-23 | Drama    | 01:44
 BL102 | The African Queen       | 101 | 1951-08-11 | Romantic | 01:43
 JL201 | Une Femme est une Femme | 102 | 1961-03-12 | Romantic | 01:25
 P_301 | Vertigo                 | 103 | 1958-11-14 | Action   | 02:08
 P_302 | Becket                  | 103 | 1964-02-03 | Drama    | 02:28</codeblock><p>-- Close the cursor and end the transaction:</p><codeblock>CLOSE mycursor;
COMMIT;</codeblock><p>Change the <codeph>kind</codeph> column of the table <codeph>films</codeph> in the row at the <codeph>c_films</codeph> cursor's current position:</p>
<codeblock>UPDATE films SET kind = 'Dramatic' WHERE CURRENT OF c_films;</codeblock>
</section><section id="section8"><title>Compatibility</title><p>SQL standard allows cursors only in embedded SQL and in modules. Greenplum
Database permits cursors to be used interactively. </p><p>The variant of <codeph>FETCH</codeph> described here returns the data
as if it were a <codeph>SELECT</codeph> result rather than placing it
in host variables. Other than this point, <codeph>FETCH</codeph> is fully
upward-compatible with the SQL standard. </p><p>The <codeph>FETCH</codeph> forms involving <codeph>FORWARD</codeph>,
as well as the forms <codeph>FETCH</codeph> count and <codeph>FETCH</codeph><codeph>ALL</codeph>, in which <codeph>FORWARD</codeph> is implicit,
are Greenplum Database extensions. <codeph>BACKWARD</codeph> is not supported.</p><p>The SQL standard allows only <codeph>FROM</codeph> preceding the cursor name; the option to use
          <codeph>IN</codeph>, or to leave them out altogether, is an extension.</p></section><section id="section9"><title>See Also</title><p><codeph><xref href="DECLARE.xml#topic1" type="topic" format="dita"/></codeph>, <codeph><xref
            href="CLOSE.xml#topic1" type="topic" format="dita"/></codeph>, <codeph><xref
            href="./MOVE.xml#topic1" type="topic" format="dita"/></codeph></p></section></body></topic>
